home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / ud897.asc < prev    next >
Text File  |  1997-06-20  |  4KB  |  145 lines

  1. _Undocumented Corner_
  2. by George Shepherd and Scot Wingo
  3.  
  4. Listing One
  5. class ATL_NO_VTABLE CDefault : 
  6.    public CComObjectRootEx<CComSingleThreadModel>,
  7.    public CComCoClass<CDefault, &CLSID_Default>,
  8.    public IDispatchImpl<IDefault, &IID_IDefault, &LIBID_ATLTESTLib>
  9. {
  10. public:
  11.    CDefault() {
  12.    }
  13. DECLARE_REGISTRY_RESOURCEID(IDR_DEFAULT)
  14. BEGIN_COM_MAP(CDefault)
  15.    COM_INTERFACE_ENTRY(IDefault)
  16.    COM_INTERFACE_ENTRY(IDispatch)
  17. END_COM_MAP()
  18. // IDefault
  19. public:
  20. };
  21.  
  22. Listing Two
  23. template <class ThreadModel>
  24. class CComObjectRootEx : public CComObjectRootBase
  25. {
  26. public:
  27.    typedef ThreadModel _ThreadModel;
  28.    typedef _ThreadModel::AutoCriticalSection _CritSec;
  29.  
  30.    ULONG InternalAddRef() {
  31.       return _ThreadModel::Increment(&m_dwRef);
  32.    }
  33.    ULONG InternalRelease() {
  34.       return _ThreadModel::Decrement(&m_dwRef);
  35.    }
  36.    void Lock() {m_critsec.Lock();}
  37.    void Unlock() {m_critsec.Unlock();}
  38. private:
  39.    _CritSec m_critsec;
  40. };
  41.  
  42. Listing Three
  43. class CComMultiThreadModelNoCS
  44. {
  45. public:
  46.     static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  47.     static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  48.     typedef CComFakeCriticalSection AutoCriticalSection;
  49.     typedef CComFakeCriticalSection CriticalSection;
  50.     typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  51. };
  52. class CComMultiThreadModel
  53. {
  54. public:
  55.     static ULONG WINAPI Increment(LPLONG p) {return InterlockedIncrement(p);}
  56.     static ULONG WINAPI Decrement(LPLONG p) {return InterlockedDecrement(p);}
  57.     typedef CComAutoCriticalSection AutoCriticalSection;
  58.     typedef CComCriticalSection CriticalSection;
  59.     typedef CComMultiThreadModelNoCS ThreadModelNoCS;
  60. };
  61. class CComSingleThreadModel
  62. {
  63. public:
  64.     static ULONG WINAPI Increment(LPLONG p) {return ++(*p);}
  65.     static ULONG WINAPI Decrement(LPLONG p) {return --(*p);}
  66.     typedef CComFakeCriticalSection AutoCriticalSection;
  67.     typedef CComFakeCriticalSection CriticalSection;
  68.     typedef CComSingleThreadModel ThreadModelNoCS;
  69. };
  70.  
  71. Listing Four
  72. Class CDefault : public IDispatch,
  73.                         IDefault {
  74.    HRESULT QueryInterface(RIID riid, 
  75.                           void** ppv) {
  76.       if(riid == IID_IDispatch)
  77.          *ppv = (IDispatch*) this;
  78.       else if(riid == IID_IDefault)
  79.          *ppv = (IDefault*) this;
  80.       else {
  81.          *ppv = 0;
  82.          return E_NOINTERFACE;
  83.       }
  84.       ((IUnknown*)(*ppv))->AddRef();
  85.       return NOERROR;
  86.    } 
  87.    // AddRef, Release, and other functions
  88. }; 
  89.  
  90. Listing Five
  91. #define BEGIN_COM_MAP(x) public: 
  92.   typedef x _ComMapClass; 
  93.   static HRESULT WINAPI _Cache(void* pv,REFIID iid,void** ppvObject,DWORD dw){
  94.      _ComMapClass* p = (_ComMapClass*)pv;
  95.       p->Lock();
  96.       HRESULT hRes = 
  97.          CComObjectRootBase::_Cache(pv, iid, ppvObject, dw);
  98.       p->Unlock();
  99.       return hRes;
  100.    }
  101.    IUnknown* GetUnknown() { 
  102.       _ASSERTE(_GetEntries()[0].pFunc == _ATL_SIMPLEMAPENTRY); 
  103.       return (IUnknown*)((int)this+_GetEntries()->dw); 
  104.    }
  105.    HRESULT _InternalQueryInterface(REFIID iid, void** ppvObject) { 
  106.       return InternalQueryInterface(this, _GetEntries(), iid, ppvObject); 
  107.    } 
  108.    const static _ATL_INTMAP_ENTRY* WINAPI _GetEntries() { 
  109.       static const _ATL_INTMAP_ENTRY _entries[] = { 
  110.                         DEBUG_QI_ENTRY(x)
  111.    ...
  112.    #define END_COM_MAP()   {NULL, 0, 0}};\
  113.     return _entries;}
  114.  
  115.  
  116. Listing Six
  117. struct _ATL_INTMAP_ENTRY {
  118.    const IID* piid;       
  119.    DWORD dw;
  120.    _ATL_CREATORARGFUNC* pFunc; 
  121. }
  122.  
  123. Listing Seven
  124. #define offsetofclass(base,derived)((DWORD)(static_cast<base*>((derived*)8))-8)
  125. #define COM_INTERFACE_ENTRY(x)\
  126.     {&IID_##x, \
  127.     offsetofclass(x, _ComMapClass), \
  128.     _ATL_SIMPLEMAPENTRY},
  129.  
  130. Listing Eight
  131. const static _ATL_INTMAP_ENTRY* __stdcall _GetEntries() { 
  132.   static const _ATL_INTMAP_ENTRY _entries[] = { 
  133.     {&IID_IDefault, 
  134.     ((DWORD)(static_cast<IDefault*>((_ComMapClass*)8))-8),
  135.     ((_ATL_CREATORARGFUNC*)1)},
  136.     {&IID_IDispatch, 
  137.     ((DWORD)(static_cast<IDispatch*>((_ComMapClass*)8))-8), 
  138.     ((_ATL_CREATORARGFUNC*)1)},
  139.     {0, 0, 0}
  140.   }; 
  141.   return _entries;
  142. }
  143.  
  144.  
  145.